package cn.hy.batch;

import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.job.builder.FlowBuilder;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;

@Configuration
@Slf4j
public class DeciderDemo {

    //注入任务对象工厂
   @Resource
    private JobBuilderFactory jobBuilderFactory;

    //任务的执行由Step决定,注入step对象的factory
   @Resource
    private StepBuilderFactory stepBuilderFactory;

    //创建Job对象
    @Bean
    public Job deciderDemo1() {
        return jobBuilderFactory.get("deciderDemo1")
                .start(step4()) // 1  执行step1
                .next(myDecider()) // 2  执行决策器,根据决策期的结果选择flow,第一次运行，返回flow-0
                .from(myDecider()).on("flow-0").to(flow2()) //3. 决策器返回flow-0 则执行 flow2
                .from(myDecider()).on("flow-1").to(flow3())  // 5. 决策器返回flow-1 则执行 flow3
                .from(flow2()).on("*").to(myDecider())  // //4. 从flow2后，不管flow2结果是什么，都再进入决策器，再次执行决策器后，返回flow-1,则执行flow3
                .end().build();
    }

    /**
     * 决策器
     *
     * @return
     */
    @Bean
    public JobExecutionDecider myDecider() {
        return new JobExecutionDecider() { //自定义决策器
            private int count;

            @Override
            public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
                String status = "flow-" + (count++ % 2);
                log.info("决策器:" + status);
                return new FlowExecutionStatus(status);
            }
        };
    }

    /**
     * 创建Flow对象，声明flow中包含哪些step
     *
     * @return
     */
    @Bean
    public Flow flow2() {
        return new FlowBuilder<Flow>("flow2").start(step4()).build();
    }

    /**
     * 创建Flow对象，声明flow中包含哪些step
     *
     * @return
     */
    @Bean
    public Flow flow3() {
        return new FlowBuilder<Flow>("flow3").start(step5()).next(step6()).build();
    }


    //创建Step对象
    @Bean
    public Step step4() {
        return stepBuilderFactory.get("step4").tasklet(new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                log.info("------step4 start");
                return RepeatStatus.FINISHED;
            }
        }).build();
    }

    //创建Step对象
    @Bean
    public Step step5() {
        return stepBuilderFactory.get("step5").tasklet(new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                log.info("------step5 start");
                return RepeatStatus.FINISHED;
            }
        }).build();
    }

    //创建Step对象
    @Bean
    public Step step6() {
        return stepBuilderFactory.get("step6").tasklet(new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                log.info("------step6 ok");
                return RepeatStatus.FINISHED;
            }
        }).build();
    }
}
